/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package it.baumi.tankwars;

import it.baumi.tankwars.util.Timer;
import it.baumi.tankwars.entities.BotEntity;
import it.baumi.tankwars.entities.WallEntity;
import it.baumi.tankwars.entities.ShotEntity;
import it.baumi.tankwars.entities.TankEntity;
import it.baumi.tankwars.entities.BlockEntity2D;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.GL11.*;

/**
 *
 * @author Michael Baumgartner
 */
public class Game {

    private final int HEIGHT = 800;
    private final int WIDTH = 1024;

    private Timer timer;

    private ArrayList<WallEntity> wallList;
    private WallEntity wall;

    private ArrayList<TankEntity> tankList;
    private ArrayList<TankEntity> removeTankList;

    private TankEntity player1;
    private TankEntity player2;
    private TankEntity player3;

    private BotEntity bot;

    public Game() {
        try {
            Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));

            Display.setTitle("Baumis Super Panzerr Spiel");
            Display.create();

            timer = new Timer();

            tankList = new ArrayList<TankEntity>();
            removeTankList = new ArrayList<TankEntity>();

            player1 = new TankEntity(this,150, 150, 30, 30, 0.15f);
            tankList.add(player1);
            bot = new BotEntity(this, 170, 600, 30, 30, 0.15f);
            tankList.add(bot);

            wallList = new ArrayList<WallEntity>();
            //oben
            wall = new WallEntity(Display.getWidth() / 2, 10, Display.getWidth(), 20);
            wallList.add(wall);
            //links    
            wall = new WallEntity(10, Display.getHeight() /2, 20, Display.getHeight());
            wallList.add(wall);
            //rechts          
            wall = new WallEntity(Display.getWidth()-10, Display.getHeight() /2, 20, Display.getHeight());
            wallList.add(wall);
            //untent
            wall = new WallEntity(Display.getWidth() / 2, Display.getHeight()-10, Display.getWidth(), 20);
            wallList.add(wall);
            
            //mitte
            wall = new WallEntity(Display.getWidth() / 4, Display.getHeight()/2, Display.getWidth()/2, 20);
            wallList.add(wall);

        } catch (LWJGLException ex) {
            Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
            Display.destroy();
        }

    }

    public int getHeight() {
        return HEIGHT;
    }

    public int getWidth() {
        return WIDTH;
    }

    public ArrayList<WallEntity> getWallList() {
        return wallList;
    }

    public ArrayList<TankEntity> getTankList() {
        return tankList;
    }

    public void start() {
        //init Timer
        timer.init();
        //init OpenGL
        initGL();
        //game loop
        while (!Display.isCloseRequested()) {
            //clear screen color for 2d , depth for 3d
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            collisionDetection();
            //render OpenGL (Entities, Tanks, etc...)
            renderGL();

            //keyboard input
            long delta = timer.getDelta();
            updateInput(delta);
            updateFPS();

            // Refresh the display and poll input.
            Display.update();

            Display.sync(60);
            // Wait until 16.67 milliseconds have passed. (Maintain 60 frames-per-second)
        }

    }

    public void initGL() {
        GL11.glMatrixMode(GL_PROJECTION);
        GL11.glLoadIdentity(); // Resets any previous projection matrices
        //legt ein Koordinatensystem über den screen, muss so groß wie das Display sein, Achsen Null Punkt links oben
        GL11.glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);
        GL11.glMatrixMode(GL_MODELVIEW);
//        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE);
    }

    public void renderGL() {
        //draw walls
        for (BlockEntity2D wall : wallList) {
            wall.update();
        }

        //draw tanks
        for (TankEntity tank : tankList) {
            if (tank.isDestroy()) {
                removeTankList.add(tank);
            } else {
                tank.update();
            }
        }
        //remove tanks
        for (TankEntity tank : removeTankList) {
            tankList.remove(tank);
        }

        //mouse fadenkreuz
        GL11.glPushMatrix();
        GL11.glBegin(GL11.GL_LINES);
        GL11.glColor3f(1.0f, 1.0f, 1.0f);
        GL11.glVertex2f(Mouse.getX(), Display.getHeight() - Mouse.getY() - 10);
        GL11.glVertex2f(Mouse.getX(), Display.getHeight() - Mouse.getY() + 10);
        GL11.glVertex2f(Mouse.getX() + 10, Display.getHeight() - Mouse.getY());
        GL11.glVertex2f(Mouse.getX() - 10, Display.getHeight() - Mouse.getY());
        GL11.glEnd();

        GL11.glPopMatrix();
    }

    //event driven input
    public void updateInput(float delta) {
        //Left Mouse Button
        if (Mouse.isButtonDown(0)) {
            player1.setFiring(true);
        } else {
            player1.setFiring(false);
        }
        //Right Mouse Button
        if (Mouse.isButtonDown(0)) {
            //  tank.fire();
        }

        if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
            player1.moveWest(delta);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
            player1.moveEast(delta);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
            player1.moveNorth(delta);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
            player1.moveSouth(delta);
        }

        if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
            player1.moveWest(delta);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
            player1.moveEast(delta);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
            player1.moveNorth(delta);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
            player1.moveSouth(delta);
        }

    }

    //Zeigt FPS im Fensterrahmen an
    public void updateFPS() {
        if (Timer.getTime() - timer.getLastFPS() > 1000) {
            Display.setTitle("FPS: " + timer.getFps() + " x: " + Mouse.getX() + " y: " + (Display.getHeight() - Mouse.getY()));
            timer.setFps(0);
            timer.setLastFPS(timer.getLastFPS() + 1000);
        }
        timer.setFps(timer.getFps() + 1);
    }

    private void collisionDetection() {
        for (TankEntity tank : tankList) {
            //Schüsse intersects Panzer
            for (ShotEntity shot : tank.getShots()) {
                //shot hits tank
                for (TankEntity otherTank : tankList) {
                    if (shot.intersects(otherTank)) {
                        shot.collideWith(otherTank);
                    }
                }
                //shot hits wall
                for (WallEntity wall : wallList) {
                    if (shot.intersects(wall)) {
                        shot.collideWith(wall);
                    }
                }

            }

            for (ShotEntity shot : player1.getShots()) {
                for (ShotEntity shot2 : bot.getShots()) {
                    if (shot.intersects(shot2)) {
                        shot.collideWith(shot2);
                    }
                }
            }

//            Panzer intersects mit anderen Panzer
            for (TankEntity otherTank : tankList) {
                if (!tank.equals(otherTank)) {
                    if (tank.intersects(otherTank)) {
                        tank.collideWith(otherTank);
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        Game game = new Game();
        //ins spiele menu
        game.start();
        //auf button druck   
    }

}
